package me.twoday.library.mine.common.network;

import me.twoday.library.mine.common.ActivityUtil;
import me.twoday.library.mine.common.LoggerUtil;
import me.twoday.library.mine.common.MessageUtil;
import me.twoday.library.mine.common.base.BaseApplication;

import org.apache.commons.lang.exception.ExceptionUtils;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import android.os.Message;

/**
 * HTTP 처리용 핸들러
 * 
 * @author 박우람
 * @since 2011.02.14
 */
public class HttpHandler extends Handler
{
	private static final String TAG = "HttpHandler";
	private static final String DEFAULT_LOADING_MSG = "로딩중입니다";
	private final LoggerUtil mLog;
	
	private ProgressDialog mPdProgress;
	private Activity mParentActivity;
	private Context mContext;
	private String mProgressMessage;
	
	/**
	 * @param context
	 */
	public HttpHandler(Context context)
	{
		this.mParentActivity = null;
		this.mContext = context;
		this.mProgressMessage = null;
		this.mLog = LoggerUtil.getInstance(TAG);
	}
	
	/**
	 * 기본 생성자
	 * 
	 * @param activity 부모 엑티비티
	 */
	public HttpHandler(Activity activity)
	{
		this.mParentActivity = activity;
		this.mContext = activity;
		this.mProgressMessage = DEFAULT_LOADING_MSG;
		this.mLog = LoggerUtil.getInstance(TAG);
	}
	
	/**
	 * 로딩시 출력메시지를 결정하는 생성자
	 * 메시지값에  null을 넣을경우 로딩 다이얼로그 없이 백그라운드로 값을 가져온다.
	 * 
	 * @param activity 부모 엑티비티
	 * @param message 출력 메시지
	 */
	public HttpHandler(Activity activity, String message)
	{
		this.mParentActivity = activity;
		this.mContext = activity;
		this.mProgressMessage = message;
		this.mLog = LoggerUtil.getInstance(TAG);
	}
	
	/**
	 * 현재 시점에서 가장 상단에 있는 엑티비티를 반환한다.
	 * 
	 * @return 엑티비티 객체
	 */
	public Activity getParentActivity()
	{
		return mParentActivity;
	}
	
	/**
	 * 컨텍스트를 반환합니다.
	 * 
	 * @return 컨텍스트 객체
	 */
	public Context getParentContext()
	{
		if(mContext != null)
		{
			return mContext;
		}
		else
		{
			return mParentActivity;
		}
	}
	
	/**
	 * HTTP 요청이 시작될 때 호출
	 */
	public void didStart() {}
	
	/**
	 * HTTP 요청이 정상적으로 종료되었을 경우 호출
	 * 
	 * @param result 응답 결과
	 */
	public void didSucceed(Object result)
	{
		mLog.d("didSucceed: " + result);		
		MessageUtil.alert(mContext, result.toString());
	}
	
	/**
	 * HTTP 요청 처리 중에 에러 발생시 호출
	 * 
	 * @param error 에러 Exception
	 */
	public void didError(MsgException error)
	{
		String errMessage = error.getMessage();
		mLog.e("didError: " + errMessage);
		
		MessageUtil.alert(mContext, errMessage);
	}
	
	public void didNetworkError()
	{
		Class<?> errorActivity = BaseApplication.getErrorActivity();
		if(errorActivity != null)
		{
			ActivityUtil activityUtil = new ActivityUtil(BaseApplication.getContext());
			//activityUtil.setRemoveTask();
			activityUtil.setNoHistory();
			activityUtil.setTargetActivity(errorActivity);
			activityUtil.show();
		}
		else
		{
			MessageUtil.alert(mContext, "네트워크 문제가 발생했습니다.\nWIFI/3G망을 확인해주세요.");
		}
	}
	
	/* (non-Javadoc)
	 * @see android.os.Handler#handleMessage(android.os.Message)
	 */
	@Override
	final public void handleMessage(Message msg)
	{
		switch (msg.what)
		{
		case HttpConnection.HTTP_DID_START:
			didStart();
			showProgressDlg();
			break;
			
		case HttpConnection.HTTP_DID_SUCCEED:
			didSucceed(msg.obj);
			dismissDlg();
			break;
			
		case HttpConnection.HTTP_DID_ERROR:
			// 메시지를 출력하기 위한 에러일경우
			if(msg.obj instanceof MsgException)
			{
				didError((MsgException) msg.obj);
			}
			// 기타 모든 에러는 네트워크 에러로 묶어서 처리한다.
			else
			{
				mLog.e("NetworkError: " + ExceptionUtils.getStackTrace((Exception)msg.obj));
				didNetworkError();
			}
			dismissDlg();
			break;
		}
	}
	
	/**
	 * HTTP 요청이 진행중임을 보여주는 다이얼로그
	 */
	private void showProgressDlg()
	{
		if(mProgressMessage != null && mParentActivity != null)
		{
			// 이미 메시지 창이 떠있을 경우 생성하지 않고 무시한다.
			if(mPdProgress != null && mPdProgress.isShowing())
			{
				return;
			}
			else
			{
				mPdProgress = new ProgressDialog(mContext);
				mPdProgress.setMessage(mProgressMessage);
				mPdProgress.setIndeterminate(true);
				mPdProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				mPdProgress.setCancelable(false);
				mPdProgress.show();
			}
		}
	}
	
	/**
	 * HTTP 요청 프로그래스 다이얼로그를 제거한다
	 */
	private void dismissDlg()
	{
		try
		{
			if(mPdProgress != null)
			{
				mPdProgress.dismiss();
			}
		}
		catch (Exception e) {}
	}
}